
<template>
  <view class="obit-cascade">
    <span class="showInfo" @click="showView" :class="{'selected':selectName !==placeholder}">{{selectName}}</span>
    <view class="mask" :class="{'maskShow' : showPicker}" @click="hide" @click.stop.prevent @touchmove.stop.prevent catchtouchmove="true"></view>
    <view class="cpicker-content" :class="{'cpickerShow' : showPicker}">
      <view class="city-head" @click.stop.prevent @touchmove.stop.prevent catchtouchmove="true">
        <view class="city-head-title">{{headtitle}}</view>
        <span class="rightIcon" v-if="rightIcon">
          <u-icon v-if="clearAllow" name="trash" size="20" @click="clearInfo('self')"></u-icon>
        </span>
      </view>
      <scroll-view id="nav-bar" class="nav-bar" scroll-x="true" scroll-with-animation="true" :scroll-left="scrollLeft">
        <view v-for="(item,index) in tabbars" class="nav-item" :key="index" :id="'tab'+index" @click="changeTab(index)"
          :style="{'color':tabCurrentIndex === index?activeColor:'','border-color':tabCurrentIndex === index?activeColor:''}" :class="{'current': index === tabCurrentIndex}">
          <text class="nav-bar-title">{{item.text}}</text>
        </view>
      </scroll-view>
      <view class="city_content">
        <scroll-view class="panel-scroll-box" :scroll-y="enableScroll" :cscrollTop="scrollTop" :current="tabCurrentIndex" :scroll-top="scrollTop">
          <block v-for="(item,index) in showList" :key="index">
            <view class="flex-row-c-c" @click="changCity(tabCurrentIndex,item,index)">
              <icon type="success_no_circle" v-if="tabbars[tabCurrentIndex].value==item.value" :id="'show'+tabCurrentIndex" class="ischeck" size="14" :color="activeColor"></icon>
              <text class="city-text">{{item.text}}</text>
            </view>
          </block>
        </scroll-view>
      </view>
    </view>
  </view>
</template>

<script>
let windowWidth = 0, scrollTimer = false, tabBar;
export default {
  name: 'UniCityNvue',
  props: {
    value: {
      type: [Number, String],
    },
    headtitle: {// 使用多少个tab
      type: String,
      default: ''
    },
    placeholder: {
      type: String,
      default: '请选择'
    },
    /**
     * 多级联动 联动配置  每一级的接口配置和key  value 
     * 二级和三级会传值查询，接口直接返回数据
     * pickerOptions: [
        { url: 'getTestprovince', title: '请选择省', key: 'adcode', value: 'name' },
        { url: 'getTestCity', title: '请选择市', key: 'adcode', value: 'name' },
        { url: 'getTestDistrict', title: '请选择区', key: 'adcode', value: 'name' },
      ],
     */
    // 
    pickerOptions: {
      type: Array,
    },
    asyn: {
      type: Boolean,
      default: true
    },
    data: {// 默认的省市区id，如果不使用id的情况下则为[]；
      type: Array,
      default: function () {
        return [];
      },
    },
    // 多级选择 是否默认展示每一级选择的名字
    showDetail: {
      type: Boolean,
      default: true
    },
    initCascadeList: {// 默认的省市区id，如果不使用id的情况下则为[]；
      type: Array,
      default: function () {
        return [];
      },
    },
    /**
     * 是否可以删除
     */
    clearAllow: {
      type: Boolean,
      default: false
    },
    activeColor: {
      type: String,
      default: "#00b1b7"
    }
  },
  data () {
    return {
      isFirst: true,
      rightIcon: true,
      scrollLeft: 500, //顶部选项卡左滑距离
      scrollTop: 0,
      enableScroll: true,
      tabCurrentIndex: 0, //当前选项卡索引
      tabbars: [{
        text: this.pickerOptions[0].title,
        value: "",
      }],
      showData: this.data,
      pickersize: '',
      showPicker: false,
      showList: [],
    }
  },
  watch: {
    value (value, oldValue) {
      if (!this.value && oldValue && this.tabbars.length === this.pickersize) {
        this.tabbars = [{
          text: this.pickerOptions[0].title,
          value: "",
        }]
        this.tabCurrentIndex = 0
        this.sysnShowList()
      }
    },
    showPicker () {
      if (this.isFirst) {
        this.isFirst = false;
      }
    },
    initCascadeList: {
      handler () {
        this.$set(this, 'tabbars', [{
          text: this.pickerOptions[0].title,
          value: "",
        }])
        this.tabCurrentIndex = 0
        this.sysnShowList()
        this.initDataSysn(0)
      },
      deep: true
    }
  },
  computed: {
    selectName () {
      let lastInfo = this.tabbars[this.tabbars.length - 1]
      if (this.tabbars.length === this.pickersize && lastInfo.value) {
        if (this.showDetail) {
          let name = ''
          this.tabbars.forEach(element => {
            name += element.text + "/"
          });
          return name.substring(0, name.length - 1)
        } else {
          return lastInfo.text
        }
      } else {
        return this.placeholder
      }

    }
  },
  mounted () {
    this.pickersize = this.pickerOptions.length
    if (this.asyn) {
      this.initData(() => {
        this.initDataSysn(0)
      })
    }
  },
  methods: {
    currentStyle (index) {
      if (this.tabCurrentIndex === index) {
        return {
          "color": this.activeColor,
          "border-color": this.activeColor
        }
      } else {
        return {}
      }
    },
    clearInfo () {
      this.tabbars = [{
        text: this.pickerOptions[0].title,
        value: "",
      }]
      this.changeTab(0)
      this.$emit('input', '');
      this.$emit('update:valueName', '');
      this.$emit('change', this.tabbars);
      this.hide();
    },
    // 数据回显
    initDataSysn (index) {
      if (this.showData.length === 0) return
      if (this.initCascadeList.length === this.pickerOptions.length) {
        let indexInfo = {
          value: this.initCascadeList[index],
        }
        for (let i = 0; i < this.showList.length; i++) {
          if (this.showList[i].value == indexInfo.value) {
            indexInfo.text = this.showList[i].text
            indexInfo.index = i
          }
        }
        // console.log('indexInfo: ', indexInfo);
        this.$set(this.tabbars, index, indexInfo)
        if (index < this.pickerOptions.length - 1) {
          if (this.tabbars.length < this.pickerOptions.length) {
            this.tabbars.push({
              text: '请选择',
              value: "",
              index: ''
            })
          }
          let next = index + 1
          this.tabCurrentIndex = next
          this.initData(() => {
            this.initDataSysn(next)
          })
        } else {
          this.$emit('change', this.tabbars);
        }
      }
    },
    // 异步获取数据   初始化第一级
    initData (callback) {
      let info = this.pickerOptions[this.tabCurrentIndex]
      let param = ''
      let root = this.showData
      let curIndex = this.tabCurrentIndex
      if (curIndex > 0) {
        param = this.tabbars[curIndex - 1].value
        this.tabbars.forEach((element, index) => {
          if (index === 0) {
            root = root[element.index]
          } else if (element.index !== '') {
            root = root.children[element.index]
          }
        });
        if (root.children && root.children.length > 0) {
          this.sysnShowList()
          callback && callback()
          return
        }
      }
      this.$http[info.url](param, this.tabbars, curIndex).then(res => {
        res.forEach(element => {
          element.text = element[info.value]
          element.value = element[info.key]
          delete element[info.key]
          delete element[info.value]
        });
        if (curIndex === 0) {
          this.showData = res
        } else {
          this.$set(root, 'children', res)
        }
        this.sysnShowList()
        callback && callback()

      })
    },
    /**
     * 同步 展示的列表
     */
    sysnShowList () {
      let root = this.showData
      let curIndex = this.tabCurrentIndex
      for (let i = 0; i < curIndex; i++) {
        root = root[this.tabbars[i].index].children
      }
      this.showList = root
    },
    showView () {
      this.showPicker = true;
      this.scrollTop = 0;
      this.setScroll(this.tabCurrentIndex);
    },
    hide () {
      this.showPicker = false;
    },
    //tab切换
    changeTab (e) {
      let index = e;
      this.setScroll(index);
      //延迟300ms,等待swiper动画结束再修改tabbar
      this.tabCurrentIndex = index;
      this.sysnShowList()
      setTimeout(() => {
        this.getScroll("show" + index);
      }, 10)
    },
    //获得元素的size
    getElSize (id) {
      return new Promise((res, rej) => {
        let el = uni.createSelectorQuery().in(this).select('#' + id);
        el.fields({
          size: true,
          scrollOffset: true,
          rect: true
        }, (data) => {
          res(data);
        }).exec();
      });
    },
    changCity (index, item, itemIndex) {
      if (this.tabbars[index].value != item.value) {
        this.tabbars[index].text = item.text;
        this.tabbars[index].value = item.value;
        this.tabbars[index].index = itemIndex;
        if (index < (this.tabbars.length - 1)) {
          this.tabbars.splice(index + 1, this.tabbars.length - index - 1)
        }
        if (this.tabbars.length < this.pickersize) {
          let info = this.pickerOptions[index + 1]
          var current = {
            text: info.title ? info.title : '请选择',
            value: "",
            index: ''
          }
          this.tabbars.push(current);
          this.tabCurrentIndex++;
          this.scrollTop = 0;
          this.initData()
          this.setScroll(index)
          // this.$emit('input', '');
        } else {
          this.$emit('input', this.tabbars[this.pickersize - 1].value);
          this.$emit('update:valueName', this.tabbars[this.pickersize - 1].text);
          this.$emit('change', this.tabbars);
          this.hide();
          this.sysnShowList()
        }
      }
    },
    async setScroll (index) {
      let width = 0;
      let nowWidth = 0;
      for (let i = 0; i <= index; i++) {
        let result = await this.getElSize('tab' + i);
        width += result.width;
        if (i === index) {
          nowWidth = result.width;
        }
      }
      if ((width + nowWidth) > windowWidth) {
        this.scrollLeft = width + nowWidth;
      } else {
        this.scrollLeft = 0;
      }
    },
    getScroll (id) {
      uni.createSelectorQuery().in(this).select('.panel-scroll-box').boundingClientRect((data) => {
        uni.createSelectorQuery().in(this).select('#' + id).boundingClientRect((res) => {
          if (res != undefined && res != null && res != '') {
            this.scrollTop = res.top - data.top;
          }
        }).exec()
      }).exec();
    }
  }
}
</script>

<style lang="scss">
/* 优惠券面板 */
.mask {
  visibility: hidden;
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  z-index: 1000;
  background: rgba(0, 0, 0, 0.6);
  opacity: 0;
  transition: all 0.3s ease;
}
.maskShow {
  visibility: visible;
  opacity: 1;
}
.cpicker-content {
  position: fixed;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: #ffffff;
  transition: all 0.3s ease;
  transform: translateY(100%);
  z-index: 1000;
}
.cpickerShow {
  transform: translateY(0);
}
.city-head {
  width: 750rpx;
  height: 88rpx;
  flex-direction: column;
  border-bottom-width: 1px;
  border-bottom-color: #f4f4f4;
  border-bottom-style: solid;
}
.city-head-title {
  font-size: 15px;
  line-height: 88rpx;
  align-items: center;
  width: 100%;
  position: absolute;
  /* #ifndef APP-NVUE */
  text-align: center;
  /* #endif */
}
.rightIcon {
  position: absolute;
  right: 30rpx;
  top: 22rpx;
  // font-size: 30px;
  color: #bebebe;
}
.nav-bar {
  position: relative;
  z-index: 10;
  height: 90upx;
  white-space: nowrap;
  box-shadow: 0 2upx 8upx rgba(0, 0, 0, 0.06);
  background-color: #fff;
}
.nav-bar::-webkit-scrollbar {
  display: none;
}
.nav-item {
  /* #ifndef APP-NVUE */
  display: inline-flex !important;
  /* #endif */
  /* #ifdef APP-NVUE */
  flex-direction: row !important;
  /* #endif */
  width: 170rpx;
  padding: 7px 0px;
  line-height: 26px;
  align-items: center;
  justify-content: center;
  color: #303133;
  position: relative;
  overflow: hidden;
  text-overflow: ellipsis;
}
.nav-bar-title {
  font-size: 12px;
}
.current {
  border-bottom-width: 4rpx;
  border-bottom-style: solid;
}
.current:after {
  width: 50%;
}
.panel-scroll-box {
  height: 516rpx;
  margin-top: 8px;
}
.flex-row-c-c {
  /* #ifndef APP-NVUE */
  display: block;
  /* #endif */
  /* #ifdef APP-NVUE */
  flex-direction: row;
  /* #endif */
  padding-left: 25px;
}
.city-text {
  /* #ifdef APP-NVUE */
  flex-direction: row;
  /* #endif */
  height: 35px;
  line-height: 35px;
  font-size: 13px;
}
.hide {
  opacity: 0;
}
.ischeck {
  /* #ifndef APP-NVUE */
  display: inline-flex !important;
  /* #endif */
  /* #ifdef APP-NVUE */
  flex-direction: column;
  /* #endif */
  margin-right: 5px;
  vertical-align: middle;
}
.selected {
  color: #000;
}
</style>